package com.faf.tools;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * AES 加密方法，是对称的密码算法(加密与解密的密钥一致)，这里使用最大的 256 位的密钥
 */
public class AESUtils {
	/**
	 * 获得一个 密钥长度为 256 位的 AES 密钥，
	 * 
	 * @return 返回经 BASE64 处理之后的密钥字符串
	 */
	public static String getStrKeyAES() {
		try {
			KeyGenerator keyGen = KeyGenerator.getInstance("AES");
			SecureRandom secureRandom = new SecureRandom(String.valueOf(System.currentTimeMillis()).getBytes("utf-8"));
			keyGen.init(256, secureRandom); // 这里可以是 128、192、256、越大越安全
			SecretKey secretKey = keyGen.generateKey();
			return Base64.getEncoder().encodeToString(secretKey.getEncoded());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 将使用 Base64 加密后的字符串类型的 secretKey 转为 SecretKey
	 * 
	 * @param strKey
	 * @return SecretKey
	 */
	private static SecretKey strKey2SecretKey(String strKey) {
		byte[] bytes = Base64.getDecoder().decode(strKey);
		SecretKeySpec secretKey = new SecretKeySpec(bytes, "AES");
		return secretKey;
	}

	/**
	 * 加密
	 * 
	 * @param content   待加密内容
	 * @param secretKey 加密使用的 AES 密钥
	 * @return 加密后的密文 byte[]
	 */
	public static String encryptAES(String content, String secretKey) {
		try {
			Cipher cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.ENCRYPT_MODE, AESUtils.strKey2SecretKey(secretKey));
			return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes("utf-8")));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 解密
	 * 
	 * @param content   待解密内容
	 * @param secretKey 解密使用的 AES 密钥
	 * @return 解密后的明文 byte[]
	 */
	public static String decryptAES(String content, String secretKey) {
		try {
			Cipher cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.DECRYPT_MODE, AESUtils.strKey2SecretKey(secretKey));
			return new String(cipher.doFinal(Base64.getDecoder().decode(content.getBytes())), "utf-8");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
}